package com.security.filter; // 过滤器类所在的包

import java.io.IOException; // IO异常处理

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; // 用户名密码认证令牌
import org.springframework.security.core.context.SecurityContextHolder; // 安全上下文持有者
import org.springframework.security.core.userdetails.UserDetails; // 用户详情接口
import org.springframework.security.core.userdetails.UserDetailsService; // 用户详情服务
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; // Web认证详情源
import org.springframework.stereotype.Component; // 组件注解
import org.springframework.web.filter.OncePerRequestFilter; // 一次性请求过滤器基类

import com.myproject.utils.JwtUtils;

import io.jsonwebtoken.ExpiredJwtException; // JWT过期异常
import io.jsonwebtoken.JwtException; // JWT异常基类
import jakarta.servlet.FilterChain; // 过滤器链
import jakarta.servlet.ServletException; // Servlet异常
import jakarta.servlet.http.HttpServletRequest; // HTTP请求
import jakarta.servlet.http.HttpServletResponse; // HTTP响应

@Component // 标记为Spring组件
public class JwtAuthenticationFilter extends OncePerRequestFilter { // 继承一次性请求过滤器

    private final JwtUtils jwtUtils; // JWT工具类实例
    private final UserDetailsService userDetailsService; // 用户详情服务实例

    // 构造器注入解决循环依赖[2](@ref)
    public JwtAuthenticationFilter(
        JwtUtils jwtUtils, 
        UserDetailsService userDetailsService
    ) {
        this.jwtUtils = jwtUtils; // 初始化JWT工具
        this.userDetailsService = userDetailsService; // 初始化用户详情服务
    }

    @Override // 重写过滤器核心方法
    protected void doFilterInternal(
        HttpServletRequest request, 
        HttpServletResponse response, 
        FilterChain filterChain
    ) throws ServletException, IOException {
        try {
            String jwt = parseJwt(request); // 从请求中解析JWT令牌
            if (jwt != null && jwtUtils.validateTokenStructure(jwt)) { // 验证令牌结构有效性
                String username = jwtUtils.extractUsername(jwt); // 从令牌提取用户名
                
                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    // 从数据库加载最新用户信息[4](@ref)
                    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                    
                    // 使用令牌中的权限信息
                    var authorities = jwtUtils.extractAuthorities(jwt);
                    
                    // 创建认证令牌
                    UsernamePasswordAuthenticationToken authentication = 
                        new UsernamePasswordAuthenticationToken(
                            userDetails, // 用户详情
                            null, // 凭证置空(因JWT已包含凭证)
                            authorities // 权限列表
                        );
                    // 设置认证详情
                    authentication.setDetails(
                        new WebAuthenticationDetailsSource().buildDetails(request)
                    );
                    // 将认证信息存入安全上下文
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        } catch (ExpiredJwtException e) {
            // 处理TOKEN过期(可添加具体处理逻辑)
        } catch (JwtException | IllegalArgumentException e) {
            // 处理无效TOKEN(可添加具体处理逻辑)
        }
        filterChain.doFilter(request, response); // 继续过滤器链
    }

    private String parseJwt(HttpServletRequest request) {
        String header = request.getHeader("Authorization"); // 获取Authorization头
        if (header != null && header.startsWith("Bearer ")) { // 检查Bearer令牌格式
            return header.substring(7); // 提取令牌部分(去掉"Bearer ")
        }
        return null; // 无有效令牌返回null
    }
}